package com.cxy.controller;

import cn.dev33.satoken.annotation.*;
import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 注解鉴权
 *
 * @author: cxy
 * @since: 2023/5/29 16:16
 * @description:
 */
@RequestMapping("/annotation_authentication")
@RestController
public class AnnotationAuthenticationController {

    // 登录校验：只有登录之后才能进入该方法
    @SaCheckLogin
    @RequestMapping("info")
    public String info() {
        return "查询用户信息";
    }

    // 角色校验：必须具有指定角色才能进入该方法
    @SaCheckRole("super-admin")
    @RequestMapping("add")
    public String add() {
        return "用户增加";
    }

    // 权限校验：必须具有指定权限才能进入该方法
    @SaCheckPermission("user-add")
    @RequestMapping("add2")
    public String add2() {
        return "用户增加";
    }

    // 二级认证校验：必须二级认证之后才能进入该方法
    @SaCheckSafe()
    @RequestMapping("add3")
    public String add3() {
        return "用户增加";
    }

    // Http Basic 校验：只有通过 Basic 认证后才能进入该方法
    @SaCheckBasic(account = "sa:123456")
    @RequestMapping("add4")
    public String add4() {
        return "用户增加";
    }

    // 校验当前账号是否被封禁 comment 服务，如果已被封禁会抛出异常，无法进入方法
    @SaCheckDisable("comment")
    @RequestMapping("send")
    public String send() {
        return "查询用户信息";
    }

    // 3、设定校验模式
    // @SaCheckRole与@SaCheckPermission注解可设置校验模式，例如：

    // 注解式鉴权：只要具有其中一个权限即可通过校验
    @RequestMapping("atJurOr")
    @SaCheckPermission(value = {"user-add", "user-all", "user-delete"}, mode = SaMode.OR)
    public SaResult atJurOr() {
        //mode有两种取值：
        //
        //SaMode.AND, 标注一组权限，会话必须全部具有才可通过校验。
        //SaMode.OR, 标注一组权限，会话只要具有其一即可通过校验。
        return SaResult.data("用户信息");
    }

    //4、角色权限双重 “or校验”
    //假设有以下业务场景：一个接口在具有权限 user.add 或角色 admin 时可以调通。怎么写？

    // 角色权限双重 “or校验”：具备指定权限或者指定角色即可通过校验
    @RequestMapping("userAdd")
    @SaCheckPermission(value = "user.add", orRole = "admin")
    public SaResult userAdd() {
        //orRole 字段代表权限认证未通过时的次要选择，两者只要其一认证成功即可通过校验，其有三种写法：
        //
        //写法一：orRole = "admin"，代表需要拥有角色 admin 。
        //写法二：orRole = {"admin", "manager", "staff"}，代表具有三个角色其一即可。
        //写法三：orRole = {"admin, manager, staff"}，代表必须同时具有三个角色。
        return SaResult.data("用户信息");
    }


}
